<script setup>
import { ref, onMounted, onUnmounted, nextTick } from 'vue';
import { marked } from 'marked';

const messages = ref([]);
const inputMessage = ref('');
const isLoading = ref(false);
const eventSource = ref(null);
const sessionId = ref(''); // 存储会话ID

// 生成UUID v4
const generateUUID = () => {
  return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
    const r = Math.random() * 16 | 0;
    const v = c === 'x' ? r : (r & 0x3 | 0x8);
    return v.toString(16);
  });
};

let lastKeyPressTime = 0;

const handleKeyDown = (event) => {
  if (event.key === 'Enter') {
    const now = Date.now();
    if (now - lastKeyPressTime < 300 && inputMessage.value.trim()) {
      sendMessage();
    }
    lastKeyPressTime = now;
  }
};

const sendMessage = () => {
  if (!inputMessage.value.trim()) return;
  
  // 添加用户消息到聊天记录
  const userMessage = {
    id: Date.now(),
    content: inputMessage.value,
    isUser: true
  };
  messages.value.push(userMessage);
  
  // 创建AI回复的占位消息
  const aiMessage = {
    id: Date.now() + 1,
    content: '',
    isUser: false
  };
  messages.value.push(aiMessage);

  scrollToBottom();
  
  // 清空输入框并设置加载状态
  const query = inputMessage.value;
  inputMessage.value = '';
  isLoading.value = true;
  
  // 关闭之前的连接（如果有）
  if (eventSource.value) {
    eventSource.value.close();
  }
  
  // 创建新的EventSource连接，传递会话ID
  const url = `/api/ai/chat/stream/all?query=${encodeURIComponent(query)}${sessionId.value ? `&sessionId=${sessionId.value}` : ''}`;
  eventSource.value = new EventSource(url);
  
  // 处理消息事件
  eventSource.value.onmessage = (event) => {
    // 使用响应式方式更新消息内容，确保Vue能够检测到变化
    const lastIndex = messages.value.length - 1;
    if (lastIndex >= 0 && !messages.value[lastIndex].isUser) {
      // 创建新对象以确保响应式更新
      const updatedMessage = { ...messages.value[lastIndex] };
      updatedMessage.content += event.data.substring(1);
      messages.value[lastIndex] = updatedMessage;
      
      // 使用Vue的nextTick确保DOM更新后再滚动
      nextTick(() => {
        scrollToBottom();
      });
    }
  };
  
  // 处理连接建立事件
  eventSource.value.onopen = () => {
    console.log('连接已建立');
  };

  // 处理错误事件
  eventSource.value.onerror = (error) => {
    console.error('EventSource 错误:', error);
    isLoading.value = false;
    eventSource.value.close();
    eventSource.value = null;
    
    // 如果AI消息为空，添加错误提示
    if (!aiMessage.content) {
      aiMessage.content = '连接错误，请稍后重试。';
    }
  };
  
  // 处理连接关闭事件
  eventSource.value.addEventListener('done', () => {
    isLoading.value = false;
    eventSource.value.close();
    eventSource.value = null;
  });
};

const scrollToBottom = () => {
  // 减少延迟时间，使滚动更及时响应
  setTimeout(() => {
    const chatContainer = document.querySelector('.chat-messages');
    if (chatContainer) {
      chatContainer.scrollTop = chatContainer.scrollHeight;
    }
  }, 10);
};

// 清除对话历史并开始新会话
const clearChat = () => {
  // 如果有会话ID，调用后端接口清除服务器端会话
  if (sessionId.value) {
    fetch(`/api/ai/chat/session/${sessionId.value}`, {
      method: 'DELETE'
    }).then(() => {
      console.log('服务器端会话已清除');
    }).catch(error => {
      console.error('清除服务器端会话失败:', error);
    });
  }
  
  // 清除消息历史
  messages.value = [];
  // 生成新的会话ID
  const newSessionId = generateUUID();
  console.log('生成新会话ID:', newSessionId);
  sessionId.value = newSessionId;
  localStorage.setItem('chatSessionId', newSessionId);
  // 如果有活动连接，关闭它
  if (eventSource.value) {
    eventSource.value.close();
    eventSource.value = null;
  }
  isLoading.value = false;
};

// 组件卸载时关闭连接
onUnmounted(() => {
  if (eventSource.value) {
    eventSource.value.close();
    eventSource.value = null;
  }
});

// 组件挂载时滚动到底部并生成新的会话ID
onMounted(() => {
  scrollToBottom();
  
  // 生成新的会话ID
  const newSessionId = generateUUID();
  console.log('生成新会话ID:', newSessionId);
  sessionId.value = newSessionId;
  localStorage.setItem('chatSessionId', newSessionId);
});
</script>

<template>
  <div class="chat-container">
    <div class="chat-header">
      <h2>测试数据生成助手</h2>
      <button @click="clearChat" class="clear-button" title="清除对话历史">
        <span>新对话</span>
      </button>
    </div>
    
    <div class="chat-messages" ref="chatContainer">
      <div v-if="messages.length === 0" class="empty-state">
        <p>开始与AI助手对话吧</p>
      </div>
      
      <div 
        v-for="message in messages" 
        :key="message.id" 
        :class="['message', message.isUser ? 'user-message' : 'ai-message']"
      >
        <div class="message-content">
          <div class="message-header">
            <span>{{ message.isUser ? '你' : 'AI' }}</span>
          </div>
          <div class="message-body">
            <div v-html="message.isUser ? message.content : marked(message.content)"></div>
          </div>
        </div>
      </div>
      
      <div v-if="isLoading" class="loading-indicator">
        <span></span>
        <span></span>
        <span></span>
      </div>
    </div>
    
    <div class="chat-input">
      <input 
        type="text" 
        v-model="inputMessage" 
        placeholder="输入消息..." 
        :disabled="isLoading"
        @keydown.enter="handleKeyDown"
      />
      <button @click="sendMessage" :disabled="isLoading || !inputMessage.trim()">
        发送
      </button>
    </div>
  </div>
</template>

<style scoped>
.chat-container {
  display: flex;
  flex-direction: column;
  height: 100%;
  width: 100%;
  max-width: 100%;
  margin: 0;
  padding: 0;
  border-radius: 0;
  overflow: hidden;
  background-color: #1a1a1a;
  box-shadow: none;
  box-sizing: border-box;
}

.chat-header {
  padding: 1rem;
  background-color: #2c2c2c;
  border-bottom: 1px solid #3a3a3a;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.chat-header h2 {
  margin: 0;
  font-size: 1.5rem;
  color: #fff;
}

.chat-messages {
  flex: 1;
  overflow-y: auto;
  padding: 1rem;
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.empty-state {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  color: #888;
  font-style: italic;
}

.message {
  display: flex;
  margin-bottom: 1rem;
}

.user-message {
  justify-content: flex-end;
}

.ai-message {
  justify-content: flex-start;
}

.message-content {
  max-width: 80%;
  border-radius: 8px;
  overflow: hidden;
}

.user-message .message-content {
  background-color: #646cff;
}

.ai-message .message-content {
  background-color: #2c3e50;
  color: #ffffff;
}

.message-header {
  padding: 0.5rem 1rem;
  font-size: 0.8rem;
  font-weight: bold;
}

.user-message .message-header {
  background-color: #535bf2;
}

.ai-message .message-header {
  background-color: #1a2533;
  color: #ffffff;
}

.message-body {
  padding: 0.5rem 1rem;
}

.message-body {
  text-align: left;
}

.message-body div {
  margin: 0;
  white-space: pre-wrap;
}

.message-body :deep(*) {
  white-space: pre-wrap;
}

/* Markdown样式 */
.message-body :deep(p) {
  margin: 0.5rem 0;
  white-space: pre-wrap;
}

.message-body :deep(pre) {
  background-color: #2d2d2d;
  padding: 0.5rem;
  border-radius: 4px;
  overflow-x: auto;
}

.message-body :deep(code) {
  font-family: monospace;
  background-color: #4a5568;
  color: #ffffff;
  padding: 0.2rem 0.4rem;
  border-radius: 3px;
}

.message-body :deep(ul), .message-body :deep(ol) {
  padding-left: 1.5rem;
  margin: 0.5rem 0;
}

.message-body :deep(blockquote) {
  border-left: 3px solid #646cff;
  padding-left: 0.8rem;
  margin: 0.5rem 0;
  color: #e2e8f0;
  background-color: #34495e;
}

.chat-input {
  display: flex;
  padding: 1rem;
  background-color: #2c2c2c;
  border-top: 1px solid #3a3a3a;
}

.chat-input input {
  flex: 1;
  padding: 0.8rem 1rem;
  border: none;
  border-radius: 4px;
  background-color: #3a3a3a;
  color: #fff;
  margin-right: 0.5rem;
}

.chat-input input:focus {
  outline: none;
  box-shadow: 0 0 0 2px rgba(100, 108, 255, 0.5);
}

.chat-input button {
  padding: 0.8rem 1.5rem;
  background-color: #646cff;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  font-weight: bold;
}

.chat-input button:hover:not(:disabled) {
  background-color: #535bf2;
}

.chat-input button:disabled {
  background-color: #4a4a4a;
  cursor: not-allowed;
  opacity: 0.7;
}

.loading-indicator {
  display: flex;
  justify-content: center;
  margin: 1rem 0;
}

.loading-indicator span {
  width: 8px;
  height: 8px;
  margin: 0 4px;
  border-radius: 50%;
  background-color: #646cff;
  animation: bounce 1.4s infinite ease-in-out both;
}

.loading-indicator span:nth-child(1) {
  animation-delay: -0.32s;
}

.loading-indicator span:nth-child(2) {
  animation-delay: -0.16s;
}

@keyframes bounce {
  0%, 80%, 100% {
    transform: scale(0);
  } 
  40% {
    transform: scale(1);
  }
}

.clear-button {
  background-color: #4a4a4a;
  color: #fff;
  border: none;
  border-radius: 4px;
  padding: 0.5rem 1rem;
  font-size: 0.9rem;
  cursor: pointer;
  transition: background-color 0.2s;
}

.clear-button:hover {
  background-color: #646cff;
}
</style>